/*
********************************************************************************
*
*
********************************************************************************
*/
#include "bsp.h"
#include "sys_ext.h"

void TIM4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));

#define APP_TIM        TIM4
#define app_timer_isr  TIM4_IRQHandler
#define APP_TIM_IRQn   TIM4_IRQn
#define APP_TIM_PERIOD 1000

/******************************************************************************
*	                            function
*******************************************************************************/
uint32_t app_tick_init (uint32_t TickPriority);
void app_tick_suspend(void);
void app_tick_resume(void);
uint32_t app_tick_get(void);
uint32_t app_tick_us_get(void);


/******************************************************************************
*	                            var
*******************************************************************************/
volatile uint32_t hal_tick_cnt = 0;
vtask_vector_type app_tick_task_list;

/*******************************************************************************
* @brief  app_tick_init
* \param[in] none
* \retval: none
*******************************************************************************/
uint32_t app_tick_init (uint32_t TickPriority)
{
    RCC_ClocksTypeDef RCC_Clocks;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, ENABLE);
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_TIM4, DISABLE);

    APP_TIM->CTLR1 = TIM_URS;
    APP_TIM->CTLR2 = 0;
    APP_TIM->SMCFGR  = 0;
    
    APP_TIM->CH1CVR = 0;
    APP_TIM->CH2CVR = 0;
    APP_TIM->CH3CVR = 0;
    APP_TIM->CH4CVR = 0;
    
    APP_TIM->CHCTLR1 = 0x6868;
    APP_TIM->CHCTLR2 = 0x6868;
    APP_TIM->CCER = 0;
    
    
    APP_TIM->DMAINTENR = TIM_UIE;
    APP_TIM->INTFR = 0;
    
    /*1ms interrupt*/
    RCC_GetClocksFreq(&RCC_Clocks);
    APP_TIM->PSC = (RCC_Clocks.PCLK1_Frequency / 1000000) * 2 - 1;
    APP_TIM->ATRLR = APP_TIM_PERIOD - 1;
    
    nvic_irq_set(APP_TIM_IRQn, 0x01, ENABLE);

    APP_TIM->CTLR1 |= TIM_CEN;
    
    vtask_list_init(&app_tick_task_list, 0);
    
	return 0;
}

/*******************************************************************************
* @brief  app_tick_suspend
* \param[in] none
* \retval: none
*******************************************************************************/
void app_tick_suspend(void)
{

}

/*******************************************************************************
* @brief  app_tick_resume
* \param[in] none
* \retval: none
*******************************************************************************/
void app_tick_resume(void)
{

}

/*******************************************************************************
* @brief  app_tick_get
* \param[in] none
* \retval: none
*******************************************************************************/
uint32_t app_tick_get(void)
{
    return hal_tick_cnt;
}

/*******************************************************************************
* @brief  app_tick_us_get
* \param[in] none
* \retval: none
*******************************************************************************/
uint32_t app_tick_us_get(void)
{
    uint32_t time_us;

    time_us = hal_tick_cnt * APP_TIM_PERIOD;
    time_us += APP_TIM->CNT;
    
    return time_us;
}


/*******************************************************************************
* @brief  app_tick_isr
* \param[in] none
* \retval: none
*******************************************************************************/
void app_timer_isr(void)
{
    APP_TIM->INTFR = 0;
    hal_tick_cnt++;
    
    vtask_list_run_once(&app_tick_task_list);
}
